<script setup>
import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as echarts from 'echarts/core'
import {
  GridComponent,
  TooltipComponent,
  LegendComponent,
  TitleComponent
} from 'echarts/components'
import { BarChart, PieChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'
import { LabelLayout } from 'echarts/features'

// 注册所需模块
echarts.use([
  GridComponent,
  BarChart,
  TooltipComponent,
  LegendComponent,
  PieChart,
  CanvasRenderer,
  LabelLayout,
  TitleComponent
])

import { getStuDegree, getStuCount } from '@/api/reportStu'

// 图表容器 refs
const barChartDom = ref(null)
const pieChartDom = ref(null)

const barChart = ref(null)
const pieChart = ref(null)

// 防抖函数
const debounce = (fn, delay) => {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn.apply(this, args), delay)
  }
}

// 封装图表初始化逻辑
const renderChart = (chartInstance, createOptionFn, data) => {
  if (!chartInstance) return
  const option = createOptionFn(data)
  chartInstance.setOption(option)
}

// 创建柱状图配置
const createBarChartOption = ({ clazzList, dataList }) => ({
  title: {
    text: '班级人数统计',
    left: 'center'
  },
  tooltip: {
    trigger: 'axis'
  },
  xAxis: {
    type: 'category',
    data: clazzList,
    axisLabel: {
      interval: 0,
      // rotate: -30,
      margin: 10,
      fontSize: 10
    }
  },
  yAxis: {
    type: 'value',
    axisLabel: {
      formatter: '{value}'
    }
  },
  series: [
    {
      name: '人数',
      type: 'bar',
      barWidth: '60%',
      data: dataList
    }
  ]
})

// 创建饼图配置
const createPieChartOption = (degreeData) => ({
  title: {
    text: '学员学历统计',
    left: 'center'
  },
  tooltip: {
    trigger: 'item'
  },
  legend: {
    top: '10%',
    left: 'center'
  },
  series: [
    {
      name: '性别分布',
      type: 'pie',
      radius: ['40%', '70%'],
      avoidLabelOverlap: false,
      itemStyle: {
        borderRadius: 10,
        borderColor: '#fff',
        borderWidth: 2
      },
      label: {
        show: false,
        position: 'center'
      },
      emphasis: {
        label: {
          show: true,
          fontSize: 20,
          fontWeight: 'bold'
        }
      },
      labelLine: {
        show: false
      },
      data: degreeData
    }
  ]
})

onMounted(async () => {
  try {
    // 初始化柱状图
    const clazzResult = await getStuCount()
    if (!clazzResult || !clazzResult.data) {
      console.error('获取班级数据失败')
      return
    }

    const { clazzList, dataList } = clazzResult.data
    if (!barChartDom.value) {
      console.error('柱状图容器未找到')
      return
    }
    barChart.value = echarts.init(barChartDom.value)
    renderChart(barChart.value, createBarChartOption, { clazzList, dataList })

    // 初始化饼图
    const degreeResult = await getStuDegree()
    if (!degreeResult || !degreeResult.data) {
      console.error('获取学历数据失败')
      return
    }

    const degreeData = degreeResult.data
    if (!pieChartDom.value) {
      console.error('饼图容器未找到')
      return
    }
    pieChart.value = echarts.init(pieChartDom.value)
    renderChart(pieChart.value, createPieChartOption, degreeData)

    // 添加 resize 监听器（带防抖）
    window.addEventListener('resize', debounce(handleResize, 300))
  } catch (error) {
    console.error('图表加载失败:', error)
  }
})

onBeforeUnmount(() => {
  if (barChart.value) barChart.value.dispose()
  if (pieChart.value) pieChart.value.dispose()
  window.removeEventListener('resize', handleResize)
})

// 窗口变化时重绘图表
const handleResize = () => {
  barChart.value?.resize()
  pieChart.value?.resize()
}
</script>

<template>
  <div class="echarts-container">
    <div class="chart-row">
      <div class="chart-item">
        <div ref="barChartDom" style="width: 100%; height: 400px;"></div>
      </div>
      <div class="chart-item">
        <div ref="pieChartDom" style="width: 100%; height: 400px;"></div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.echarts-container {
  padding: 20px;
}

.chart-row {
  display: flex;
  gap: 40px; /* 两个图表之间的间距 */
}

.chart-item {
  flex: 1;
  min-width: 400px; /* 最小宽度防止压缩过度 */
}
</style>